package com.gulimall.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.gulimall.cart.feigh.SkuInfoFeignService;
import com.gulimall.cart.interceptor.CartInterceptor;
import com.gulimall.cart.service.CartService;
import com.gulimall.cart.vo.CartItemVo;
import com.gulimall.cart.vo.CartVo;
import com.gulimall.cart.vo.SkuInfo;
import com.gulimall.common.constants.RedisKeyPrefix;
import com.gulimall.common.utils.R;
import com.gulimall.common.vo.LoginInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author coder_ccy
 * @date 2022/4/7 14:40
 */

@Service
public class CartServiceImpl implements CartService {


    @Autowired
    private StringRedisTemplate redisTemplate;


    @Resource
    private SkuInfoFeignService skuInfoFeignService;


    private BoundHashOperations<String, Object, Object>  getCartOps(){

        LoginInfo loginInfo = CartInterceptor.loginInfoThreadLocal.get();
        // redis使用规范：  要有前缀  要有过期时间

        String key;
        if(loginInfo!=null  && loginInfo.getId()!=null){ //远程购物车  redis   key:  前缀+4

            //redisTemplate.opsForHash().put("前缀+id",skuId,cartvo);
            key  = RedisKeyPrefix.CART_CARTINFO.getKeyPrefix()+ loginInfo.getId();
        }else{  //本地购物车   redis   key:  前缀+dsf;aihsfahf;lksa
            key = RedisKeyPrefix.CART_CARTINFO.getKeyPrefix()+loginInfo.getUserKey();
        }
        BoundHashOperations<String, Object, Object> hashOps = redisTemplate.boundHashOps(key);
        return hashOps;
    }


    // 添加购物车
    @Override
    public void addCart(long skuId,int num){

        BoundHashOperations<String, Object, Object> ops = getCartOps();
        String o = (String)ops.get(String.valueOf(skuId));
        CartItemVo cartItemVo = null;
        if(o==null){  // 表示没有对象cartItem
            cartItemVo = new CartItemVo();

            // 通过skuId 获取skuinfo信息
            R r = skuInfoFeignService.info(skuId);
            SkuInfo sku = r.getData("skuInfo",new TypeReference<SkuInfo>() {
            });

            cartItemVo.setSkuId(skuId);
            cartItemVo.setTitle(sku.getSkuTitle());
            cartItemVo.setPrice(sku.getPrice());
            cartItemVo.setCount(num);
            cartItemVo.setImage(sku.getSkuDefaultImg());

            //  转发【服务器跳转】相当于一次请求，一次响应，地址栏不变化  重定向【客户端跳转】  地址栏就是变化的

            // 接口幂等？  crud    c  create 不幂等


            ops.put(skuId+"", JSON.toJSONString(cartItemVo));

        }else{// 已经存在，改变数量

            cartItemVo = JSON.parseObject(o,CartItemVo.class);
            cartItemVo.setCount(cartItemVo.getCount()+num);


            ops.put(skuId+"", JSON.toJSONString(cartItemVo));


        }
    }

    @Override
    public CartItemVo getCartItemVoBySkuId(long skuId) {
        CartItemVo cartItemVo = null;
        BoundHashOperations<String, Object, Object> ops = getCartOps();
        String o = (String)ops.get(String.valueOf(skuId));
        if(StringUtils.isNotEmpty(o)){
            cartItemVo = JSON.parseObject(o,CartItemVo.class);
        }

        return cartItemVo;
    }


    @Override
    public List<CartItemVo> getCartItemsByKey(String key){
        BoundHashOperations<String, Object, Object> hashOps = redisTemplate.boundHashOps(key);

        List<CartItemVo> cartItemVos = hashOps.values().stream().map((obj) -> {
            String cartItemStr = (String)obj;
            CartItemVo cartItemVo = JSON.parseObject(cartItemStr, CartItemVo.class);

            return cartItemVo;
        }).collect(Collectors.toList());


        return cartItemVos;


    }

    @Override
    public CartVo getCart() {
        CartVo cartVo = new CartVo();


        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        List<CartItemVo> cartItemVos = cartOps.values().stream().map((obj) -> {
            String cartItemVo = (String) obj;
            return JSON.parseObject(cartItemVo, CartItemVo.class);

        }).collect(Collectors.toList());

        if(cartItemVos!=null && cartItemVos.size()>0){
            cartVo.setItems(cartItemVos);
        }


        return cartVo;
    }

    @Override
    public void clearCart(String cartKey) {
        redisTemplate.delete(cartKey);
    }
}
